package com.itheima.tanhua.dubbo.mq;

import cn.hutool.core.collection.CollUtil;
import com.itheima.tanhua.autoconfig.template.OssTemplate;
import com.itheima.tanhua.dubbo.api.MovementService;
import com.itheima.tanhua.model.domain.Movement;
import com.itheima.tanhua.model.dto.RabbitMovementDto;
import com.itheima.tanhua.model.dto.RabbitMovementMediaDto;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Component
public class SpringRabbitListener {


    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private MovementService movementService;

    /**
     * value     指定队列
     * exchange  指定交换机
     * - name      交换机名称
     * - type      交换规则
     * key       路由规则（direct和topic才需要）
     */
    @RabbitListener(bindings = @QueueBinding(
            // 我是消费者，我要跟 direct.queue1 这个队列进行绑定
            value = @Queue(name = "direct.queue1"),

            // 交换器
            exchange = @Exchange(name = "tanhua.movement", type = ExchangeTypes.DIRECT),

            // bingingKey
            key = {"sendMovement"}
    ))
    // 方法的形参，其实就是对应 生产者 convertAndSend的时候，传进来的第三个参数的类型。
    // 所以这个形参，代表的就是我接收到的消息
    public void listenFanoutQueue1(RabbitMovementDto rabbitMovementDto) {
        if (Objects.isNull(rabbitMovementDto)) {
            return;
        }

        // 步骤一：获取图片数据
        List<RabbitMovementMediaDto> imageContent = rabbitMovementDto.getImageContent();
        // 因为OSS上传 要求使用inputStream的方式，所以我需要将接收到的byte数组，转为inputStream
        // 再进行上传
        List<String> urlList = new ArrayList<>();
        if (CollUtil.isNotEmpty(imageContent)) {

            // 步骤二：遍历图片数组
            for (RabbitMovementMediaDto rabbitMovementMediaDto : imageContent) {
                // 获取后缀名
                String contentType = rabbitMovementMediaDto.getContentType();
                if (StringUtils.isEmpty(contentType)) {
                    continue;
                }

                // 步骤三：获取后缀名（分割）
                String suffix = contentType.split("/")[1];

                // 步骤四：将byte数组的图片 转为 inputStream
                byte[] is = rabbitMovementMediaDto.getIs();
                InputStream inputStream = new ByteArrayInputStream(is);

                // 步骤五：执行上传（执行成功后，我会得到一个oss图片地址）
                String uploaded = ossTemplate.upload(suffix, inputStream);

                // 步骤六：因为图片有多张，所以每次上传后，要将图片组装到一个集合中，后续写入数据库要用
                urlList.add(uploaded);
            }
        }

        // 步骤七：组装数据，准备写入数据库
        Movement movement = new Movement();
        BeanUtils.copyProperties(rabbitMovementDto, movement);
        movement.setMedias(urlList);

        // 步骤八：执行写入数据库操作
        movementService.sendMovement(movement);
    }

    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}